<?php

class View extends Base {

  /** @var object The model to work with. */
  protected $Model = NULL;

  /** @var object The template object. */
  protected $Template = NULL;

  /** @var string The path where are located the templates. */
  protected $path = "";

  /** @var string The template filename. */
  protected $filename = "";

  /** @var const Defines if the view is used only as a translation. */

  const __TRANSLATION = 1;

  /**
   * Store the model in private and build the template object.
   * @param Base $Model The model to work on.
   * @param string $template the template filename.
   * @param string $path The path to the template filename.
   */
  public function __construct($Model, $filename, $path = "templates/") {
    if (is_object($Model) && is_string($filename) && is_string($path)) {
      $this->filename = $filename;
      $this->path = $path;
      $this->Model = $Model;

      $this->Template = new Template($filename, $path);

      if (!is_null($this->Model))
        $this->Parse();
    }
    else
    if ($Model == View::__TRANSLATION) {
      $this->filename = $filename;
      $this->path = $path;

      $this->Template = new Template($filename, $path);
    }
    else
      throw new IllegalArgumentException("\$Model parameter should be an associated model object or View::__TRANSLATION constant.");
  }

  /**
   * Parse automatically each class property present in the template and display the template after parsing.
   * @link http://fr2.php.net/manual/en/function.get-class-methods.php
   * @link http://fr2.php.net/manual/en/function.get-class.php
   * @link http://fr2.php.net/manual/en/function.count.php
   * @link http://fr2.php.net/manual/en/function.substr.php
   * @link http://fr2.php.net/manual/en/function.strlen.php
   */
  private function parse() {
    $getters = get_class_methods(get_class($this->Model));
    $counter = count($getters);

    for ($i = 0; $i < $counter; ++$i)
      if (substr($getters[$i], 0, 3) == "get") {
        try {
          $myReflector = new ReflectionMethod(get_class($this->Model), $getters[$i]);

          if ($myReflector->getNumberOfRequiredParameters() == 0) {
            $this->Template->SetValue(substr($getters[$i], 3, strlen($getters[$i])), strval($this->Model->{$getters[$i]}()));
          }
        } catch (Exception $ex) {
          error_log($ex->__toString());
          error_log(get_class($this->Model) . "::" . $getters[$i]);
        }
      }
  }

  /**
   * This method allows you to translate a template automatically.<br />
   * If there is a file with the same name of the template and the <.lang> extension, in JSON format,
   * it will be parsed and all notified [label]'s will be replaced with their notation in the JSON array.
   * @param string $language The name of the array in the JSON file to use to match all notified [label]'s
   * @link http://be.php.net/manual/en/function.is-string.php
   * @link http://be.php.net/manual/en/function.empty.php
   * @link http://be.php.net/manual/en/function.file-exists.php
   * @link http://be.php.net/manual/en/function.json-decode.php
   * @link http://be.php.net/manual/en/function.file-get-contents.php
   * @link http://be2.php.net/manual/en/function.htmlspecialchars.php
   */
  public function translate($language) {
    if (is_string($language) && !empty($language)) {
      if (file_exists($this->path . $this->filename . ".json")) {
        $translation = json_decode(file_get_contents($this->path . $this->filename . ".json"), TRUE);

        foreach ($translation[$language] as $key => $value)
          if (is_string($value))
            $this->SetLabel($key, utf8_decode($value));
          else
            throw new IllegalArgumentException("The json file must contains only strings.");
      }
      else
        throw new FileNotFoundException("The file '" . $this->filename . "' was not found.");
    }
    else
      throw new IllegalArgumentException("The variable \$language must be a string.");
  }

  /**
   * Sets a value in the template.
   * @param string $key The key to identify.
   * @param string $value The value to replace.
   * @link http://be2.php.net/manual/en/function.is-string.php
   */
  public function setValue($key, $value) {
    if (is_string($key) && is_string($value))
      $this->Template->SetValue($key, $value);
    else
      throw new IllegalArgumentException("\$key and \$value parameters must be a string");
  }

  /**
   * Set a label in the template.
   * @param string $key The key to identify.
   * @param string $value The value to replace.
   * @link http://be2.php.net/manual/en/function.is-string.php
   */
  public function setLabel($key, $value) {
    if (is_string($key) && !empty($key) && is_string($value) && !empty($value))
      $this->Template->SetLabel($key, $value);
    else
      throw new IllegalArgumentException("\$key and \$value parameters must be strings.");
  }

  /** Displays the html source. */
  public function display() {
    $this->Template->Display();
  }

  /**
   * Returns the html source.
   * @return string Returns the html source.
   */
  public function getSource() {
    return $this->Template->getSource();
  }

}

?>
